package com.sz.mes.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.D;
import com.diboot.core.util.V;
import com.diboot.core.vo.JsonResult;
import com.diboot.core.vo.Status;

import com.diboot.file.controller.BaseExcelFileController;
import com.diboot.file.excel.listener.ReadExcelListener;
import com.diboot.file.util.ExcelHelper;

import com.sz.mes.entity.RequestPurchase;
import com.sz.mes.dto.RequestPurchaseDTO;
import com.sz.mes.mapper.RequestPurchaseMapper;
import com.sz.mes.service.RequestPurchaseService;
import com.sz.mes.vo.RequestPurchaseListVO;
import com.sz.mes.excel.listener.RequestPurchaseImportListener;
import com.sz.mes.excel.model.RequestPurchaseImportModel;
import com.sz.mes.excel.model.RequestPurchaseExportModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.diboot.iam.annotation.OperationCons;
import com.diboot.iam.annotation.BindPermission;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 请购订单 Excel处理Controller
 *
 * @author hem
 * @version 1.0
 * @date 2024-01-10
 * Copyright © szhs
 */
@RestController
@RequestMapping("/requestPurchase/excel")
@BindPermission(name = "请购订单导入导出", code = "RequestPurchaseExcel")
@Slf4j
public class RequestPurchaseExcelController extends BaseExcelFileController {

    @Autowired
    private RequestPurchaseService requestPurchaseService;


    @Autowired
    private RequestPurchaseMapper requestPurchaseMapper;

    /**
     * 预览数据
     *
     * @param file
     * @param params
     * @throws Exception
     */
    @BindPermission(name = "导入预览", code = OperationCons.CODE_IMPORT)
    @PostMapping("/preview")
    public JsonResult preview(@RequestParam("file") MultipartFile file, @RequestParam Map<String, Object> params) throws Exception {
//        requestPurchaseMapper.deleteAll();
        requestPurchaseMapper.truncateAll();
        return super.excelPreview(file, RequestPurchase.class, params);
    }

    /**
     * 导入预览保存
     *
     * @param params
     * @throws Exception
     */
    @BindPermission(name = "导入预览保存", code = OperationCons.CODE_IMPORT)
    @PostMapping("/previewSave")
    public JsonResult previewSave(@RequestParam Map<String, Object> params) throws Exception {
//        requestPurchaseMapper.deleteAll();
        requestPurchaseMapper.truncateAll();
        return super.excelPreviewSave(params);
    }

    /**
     * 上传excel并保存
     *
     * @param file
     * @param params
     * @throws Exception
     */
    @BindPermission(name = "直接导入", code = OperationCons.CODE_IMPORT)
    @PostMapping("/upload")
    public JsonResult upload(@RequestParam("file") MultipartFile file, @RequestParam Map<String, Object> params) throws Exception {
//        requestPurchaseMapper.deleteAll();
        requestPurchaseMapper.truncateAll();
        return super.uploadExcelFile(file, RequestPurchase.class, params);
    }

    /**
     * 下载示例文件
     *
     * @param response
     * @throws Exception
     */
    @BindPermission(name = "导入请购订单示例文件下载", code = OperationCons.CODE_IMPORT)
    @GetMapping("/downloadExample")
    public void downloadExample(HttpServletResponse response) throws Exception {
        String fileName = "请购订单导入示例.xlsx";
        ExcelHelper.exportExcel(response, fileName, RequestPurchaseImportModel.class, null);
    }

    /**
     * 请购订单列表导出
     *
     * @param response
     * @return
     * @throws Exception
     */
    @BindPermission(name = "导出列表文件", code = OperationCons.CODE_EXPORT)
    @GetMapping("/export")
    public JsonResult export(RequestPurchaseDTO requestPurchaseDto, @RequestParam(value = "columns", required = false) List<String> columns,
                             HttpServletResponse response) throws Exception {
        QueryWrapper<RequestPurchase> queryWrapper = super.buildQueryWrapperByQueryParams(requestPurchaseDto);
        List<RequestPurchaseListVO> requestPurchaseList = requestPurchaseService.getViewObjectList(queryWrapper, null, RequestPurchaseListVO.class);
        if (V.isEmpty(requestPurchaseList)) {
            return new JsonResult(Status.FAIL_OPERATION, "请购订单列表为空，导出失败");
        }
        String fileName = "请购订单列表导出_" + D.today() + ".xlsx";
        List<RequestPurchaseExportModel> dataList = this.entityList2ExcelList(requestPurchaseList);
        ExcelHelper.exportExcel(response, fileName, RequestPurchaseExportModel.class, columns, dataList);
        return null;
    }

    /**
     * 实体列表转excel列表
     *
     * @param requestPurchaseList
     * @return
     */
    private List<RequestPurchaseExportModel> entityList2ExcelList(List<RequestPurchaseListVO> requestPurchaseList) {
        if (V.isEmpty(requestPurchaseList)) {
            return Collections.emptyList();
        }
        return BeanUtils.convertList(requestPurchaseList, RequestPurchaseExportModel.class);
    }

    @Override
    protected ReadExcelListener<RequestPurchaseImportModel> getExcelDataListener() {
        return new RequestPurchaseImportListener();
    }

    /**
     * 上传excel并保存
     *
     * @param file
     * @param params
     * @throws Exception
     */
    @BindPermission(name = "重复数据执行更新", code = OperationCons.CODE_IMPORT)
    @PostMapping("/update")
    public JsonResult update(@RequestParam("file") MultipartFile file, @RequestParam Map<String, Object> params) throws Exception {

        ExecutorService threadPool = Executors.newFixedThreadPool(5);
        threadPool.submit(() -> {
            ArrayList<RequestPurchaseImportModel> requestPurchaseImportModels = new ArrayList<>();
            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
                EasyExcel.read(inputStream, RequestPurchaseImportModel.class, new AnalysisEventListener<RequestPurchaseImportModel>() {
                    @Override
                    public void invoke(RequestPurchaseImportModel reportExcel, AnalysisContext analysisContext) {
                        // 将读取到的每一行存入reportDetails集合中
                        requestPurchaseImportModels.add(reportExcel);
                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                    }
                }).sheet().doRead();
            } catch (IOException e) {
                e.printStackTrace();
            }
            List<RequestPurchase> requestPurchaseList = requestPurchaseMapper.selectList(null);
            if (requestPurchaseList.size() > 0) {
                try {
                    List<RequestPurchaseImportModel> requestPurchaseImportModelList = BeanUtils.convertList(requestPurchaseList, RequestPurchaseImportModel.class);
                    List<RequestPurchaseImportModel> result = requestPurchaseImportModelList.stream()
                            .filter(a -> !requestPurchaseImportModelList.contains(a))
                            .collect(Collectors.toList());
                    //后续在此处进行业务处理
                    if (result.size() > 0) {
                        for (RequestPurchaseImportModel requestPurchaseImportModel : result) {
                            QueryWrapper<RequestPurchase> wrapper = new QueryWrapper<>();
                            wrapper.eq("receipt_num", requestPurchaseImportModel.getReceiptNum());
                            wrapper.eq("receipt_num_row", requestPurchaseImportModel.getReceiptNumRow());
                            RequestPurchase requestPurchaseDB = requestPurchaseMapper.selectOne(wrapper);
                            RequestPurchase requestPurchase = BeanUtils.convert(requestPurchaseImportModel, RequestPurchase.class);
                            if (requestPurchaseDB != null) {
                                Long id = requestPurchaseDB.getId();
                                requestPurchase.setId(id);
                                requestPurchaseMapper.updateById(requestPurchase);
                            } else {
                                requestPurchaseMapper.insert(requestPurchase);
                            }

                        }
                    }

                } finally {
                    threadPool.shutdown();
                }
            }
        });
        return JsonResult.OK();
    }
}
